package evs.location;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.xml.sax.InputSource;

public class PostRequestHandler extends AbstractRequestHandler
{
    public PostRequestHandler( HttpServletRequest request, SessionFactory sessionFactory,
                    List<Class<?>> interceptorClasses, EntityMap entityMap ) throws EvsException
    {
        super( request, sessionFactory, interceptorClasses, entityMap );
    }

    @Override
    protected void _execute( HttpServletResponse response ) throws EvsException
    {
        if ( _entityId != null )
            throw new EvsException( HttpServletResponse.SC_BAD_REQUEST, "POST do not allow for giving an ID." );
        
        Session session = null;
        Transaction tx = null;
        
        try
        {
            Class<?> expectedEntityClass = _getExpectedEntityClass();
            EntityDom dom = _mediaType == MediaType.XML ? 
                EntityDom.fromXML( new InputSource( _request.getInputStream() ) ) :
                EntityDom.fromJSON( new InputStreamReader( _request.getInputStream() ) );
            
            if ( !dom.name.equals( expectedEntityClass.getSimpleName() ) ) 
                throw new EvsException( HttpServletResponse.SC_BAD_REQUEST, 
                                "Serialized content (class=" + dom.name + 
                                ") does not match expected entity type (class = " + 
                                expectedEntityClass.getName() + " )" );
        
            session = _sessionFactory.openSession();
            tx = session.beginTransaction();
            
            EntityDeserializer deserializer = new EntityDeserializer( _entityMap, false, true );
            
            Object entity = deserializer.createEntity( dom, session, false );
            String resultId = _entityMap.getId( entity ).toString();
            
            tx.commit();
            tx = null;
            
            response.getWriter().write( resultId );
        }
        catch ( ConstraintViolationException e )
        {
            throw new EvsException( HttpServletResponse.SC_BAD_REQUEST, 
                            "Constraint Violation: " + e.getMessage() );
        }
        catch ( IOException e )
        {
            throw new EvsException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage() );
        }
        finally
        {
            if ( tx!= null )
            {
                tx.rollback();
                tx = null;
            }
            
            if ( session != null )
            {
                session.close();
            }
        }
    }

    @Override protected boolean allowUnknownMediaType() { return false; }
}
